from flask import render_template,views,request,make_response
from flask import g
from flask_restful import marshal_with,marshal
from ext import db
import uuid
import os

from base.views import ViewBase  #flask的原生视图类
from base.views import ResourceBase #api的视图类
from base.response import NewResponse #响应对象
from base.password import check_password,set_password #密码加密和检测
from base.authentication import jwt_encode_token #生成token字符串
from base.model_to_iterable import model_to_dict_list # 将模型对象转成列表套字段格式
from ext import socketio
from . import serializers
from . import models
#流量控制
from base.limiter_decorator import user_limiter
from base.limiter_decorator import login_limiter
from base.limiter_decorator import register_limiter
#restful分页器
from base.pagination import GenericPagination
#异步任务
from celery_task.async_task import send_email_task,cache_user_task,save_file_task
from flask import current_app
#公共变量
from utils.key_public import STATIC_PATH,BASE_PATH
from utils.fun_pubilc import create_dir_fun
#用户注册
class RegisterResource(ResourceBase):
    decorators = [register_limiter]
    def post(self):
        data = serializers.register_parser.parse_args()
        user = models.UserModel.query.filter_by(account = data.get('account')).first()
        if user:
            return NewResponse(error='该用户名已经存在了')
        user = models.UserModel.query.filter_by(account=data.get('phoneNumber')).first()
        #将用户的密码进行加密
        data['password'] = set_password(data.get('password'))
        if user:
            return NewResponse(error='该手机号码已经存在了')

        obj = models.UserModel(**data)
        db.session.add(obj)
        db.session.commit()
        return NewResponse(msg='注册用户成功')

#用户登录
class LoginResource(ResourceBase):
    decorators = [login_limiter]
    def post(self):
        data = serializers.login_parser.parse_args()
        user = models.UserModel.query.filter_by(account=data.get('account')).first()
        if not user:
            return NewResponse(error='该用户不存在了')
        hashpwd = user.password
        #校验密码是否正确
        if check_password(data.get('password'),hashpwd):
            token = jwt_encode_token(user_id=user.id)
            response = make_response({'code':200,'msg':'登录成功','token':token})
            #将生成的token存放到cookies中
            response.set_cookie('token',token)
            return response
        else:
            return NewResponse(error='用户名或密码错误')

#家目录：需要token才能访问
class HomeResource(ResourceBase):
    def get(self):
        print(request.url_rule,request.endpoint)
        print(g.__dict__,'当前登录用户信息')
        return NewResponse()

#用户资源：get和post，获取多个和新增用户（改为注册功能了）
class UserResource(ResourceBase):
    def get(self):
        users = models.UserModel.query.all()
        data = marshal(users,serializers.user_fields)
        return NewResponse(data=data)

    def put(self):
        # 测试异步发邮件
        email = request.args.get('email')
        code = request.args.get('code')
        res = send_email_task.delay(email, code)
        print(res.id)
        return NewResponse(msg='put', data={'task_id': res.id})

    def patch(self):
        # 测试异步操作flask的orm和cache
        p = request.args.get('p')
        if p == 'set':
            res = cache_user_task.delay()
            print(res, type(res))
            return NewResponse(msg='patch', data={'task_id': res.id})
        else:
            from ext import cache
            data = cache.get('all-user-data')
            return NewResponse(msg='patch', data=data)

    def delete(self):
        return NewResponse(msg='delete')

#用户资源：get\put\delete, 对单个进行操作
class UserOneResource(ResourceBase):
    def get(self,id):

        user = models.UserModel.query.all()
        print(user)
        print(type(user),len(user))
        if not user:
            return NewResponse(error='查询不到数据')
        data = marshal(user,fields=serializers.user_fields)
        pagination = GenericPagination(data)

        return NewResponse(pagenation=pagination.start())
    def put(self,id):
        '''
        用户更新头像的接口
        '''
        file = request.files.get('picture')
        if not file:
            return NewResponse(error='请携带头像文件')
        user = models.UserModel.query.filter_by(id=id).first()

        if not user:
            return NewResponse(error='用户不存在')
        # print(file.filename,'=============')
        _,suffix = file.filename.split('.')
        #1、使用uuid创建文件名
        file_name = str(uuid.uuid4())+f'-{id}'+'.'+suffix
        file_path = os.path.join(STATIC_PATH,'picture',file_name).replace('\\','/')
        #2、读取出旧的头像路径
        delete_file_path = None
        if user.picture:
            picture = user.picture
            if picture[0] in ['\\','/']:
                picture = picture[1:]
            delete_file_path = os.path.join(BASE_PATH,picture).replace('\\','/')
            print(delete_file_path)
        #3、读取文件字节码
        file_bytes = file.read()
        #4、调用异步保存文件任务
        res = save_file_task.delay(file_bytes,file_path,delete_file_path)
        task_id = res.id
        #5、将头像新路径保存到数据库中

        picture = file_path.split('static/')[-1]
        picture = 'static/' + picture.replace('\\','/')
        user.picture = picture
        db.session.add(user)
        db.session.commit()
        return NewResponse(data={'task_id':task_id},msg='操作成功')


#用于检验celery任务状态的
class CheckCeleryTaskResource(ResourceBase):
    def get(self):
        '''
        根据celery的任务id，返回任务的运行状态
        '''
        from celery_task.check_task import check_task_status
        task_id = request.args.get('task_id')
        data = check_task_status(task_id)
        return NewResponse(pagenation=data)
    def post(self):
        #执行异步任务
        from celery_task.async_task import test_check_fun
        res = test_check_fun.delay()
        return NewResponse(data={'task_id':res.id})
